﻿namespace HutongGames.PlayMakerEditor
{
    using HutongGames.PlayMaker;
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Runtime.InteropServices;
    using UnityEditor;
    using UnityEngine;
    using AddOn;

    internal class FsmGraphView
    {
        private float autoPanRampUp;
        private Rect canvas;
        private const float CanvasPadding = 200f;
        private Vector2 canvasSize;
        private Vector2 contextMenuPos;
        private Vector2 currentMousePos;
        private DragConstraint dragConstraint;
        private DraggingMode draggingMode;
        private bool dragStarted;
        private Vector2 dragStartPos;
        private List<Vector2> dragStartPositions;
        private const float DragThreshold = 3f;
        private readonly FsmState dummyDraggingState = new FsmState(null);
        private bool frameState;
        private bool graphRepainted;
        private bool isAutoPanning;
        private bool isPanningToPosition;
        public const float MaxPossibleCanvasSize = 20000f;
        private FsmTransition mouseOverGlobalTransition;
        private FsmState mouseOverState;
        private FsmTransition mouseOverTransition;
        private int numTilesX;
        private int numTilesY;
        private Vector2 panToPositionEnd;
        private float panToPositionLerp;
        private Vector2 panToPositionStart;
        private string savedScreenshot;
        private int screenshotHeight;
        private Vector2 screenshotStartScrollPosition;
        private Texture2D screenshotTexture;
        private Rect screenshotView;
        private int screenshotWidth;
        private static FsmTransition selectedGlobalTransition;
        private bool showSavedScreenshotdialog;
        private bool takingScreenshot;
        private int tileOffsetX;
        private int tileOffsetY;
        private Rect view;

        public void AddDevice()
        {
            EditorCommands.AddDevice(this.contextMenuPos);
        }

        public void AddUnit()
        {
            EditorCommands.AddUnit(this.contextMenuPos);
        }

        public void AddFSM()
        {
            EditorCommands.AddFSM(this.contextMenuPos);
        }

        public void AddState()
        {
            EditorCommands.AddState(this.contextMenuPos);
        }

        private void CaptureNextScreenshotCell()
        {
            if (this.tileOffsetX == this.numTilesX)
            {
                this.tileOffsetY++;
                if (this.tileOffsetY == this.numTilesY)
                {
                    this.SaveScreenShot(FsmEditorUtility.GetFullFsmLabel(FsmEditor.SelectedFsm).Replace(" : ", "."), true);
                }
                else
                {
                    this.tileOffsetX = 0;
                    this.SetScrollPosition(new Vector2(this.tileOffsetX * this.screenshotView.width, this.tileOffsetY * this.screenshotView.height));
                    FsmEditor.Repaint(true);
                    this.graphRepainted = false;
                }
            }
            else
            {
                this.CaptureScreenshotCell();
                this.tileOffsetX++;
                this.SetScrollPosition(new Vector2(this.tileOffsetX * this.screenshotView.width, this.tileOffsetY * this.screenshotView.height));
                FsmEditor.Repaint(true);
                this.graphRepainted = false;
                FsmEditor.Repaint(true);
            }
        }

        private void CaptureScreenshotCell()
        {
            Rect source = new Rect(this.screenshotView);
            int destX = this.tileOffsetX * ((int) this.screenshotView.width);
            int destY = this.screenshotHeight - ((this.tileOffsetY + 1) * ((int) this.screenshotView.height));
            if (this.tileOffsetX == (this.numTilesX - 1))
            {
                source.width = this.screenshotWidth - (this.tileOffsetX * this.screenshotView.width);
                source.x = this.screenshotView.width - source.width;
            }
            if (this.tileOffsetY == (this.numTilesY - 1))
            {
                source.height = this.screenshotHeight - (this.tileOffsetY * this.screenshotView.height);
                destY = 0;
            }
            this.screenshotTexture.ReadPixels(source, destX, destY);
            this.screenshotTexture.Apply();
        }

        private void ConstrainDragToAxis()
        {
            float f = Event.current.mousePosition.x - this.dragStartPos.x;
            float num2 = Event.current.mousePosition.y - this.dragStartPos.y;
            this.dragConstraint = (Mathf.Abs(f) > Mathf.Abs(num2)) ? DragConstraint.X : DragConstraint.Y;
            if (this.dragConstraint == DragConstraint.X)
            {
                int num3 = 0;
                foreach (FsmState state in FsmEditor.SelectedStates)
                {
                    state.Position = new Rect(state.Position.x, this.dragStartPositions[num3].y, state.Position.width, state.Position.height);
                    num3++;
                }
            }
            else
            {
                int num4 = 0;
                foreach (FsmState state2 in FsmEditor.SelectedStates)
                {
                    state2.Position = new Rect(this.dragStartPositions[num4].x, state2.Position.y, state2.Position.width, state2.Position.height);
                    num4++;
                }
            }
        }

        private static void ContextMenuSelectEvent(object userdata)
        {
            FsmEvent fsmEvent = (FsmEvent) userdata;
            FsmEditor.Builder.AddEvent(FsmEditor.SelectedFsm, fsmEvent);
            FsmEditor.Builder.SetTransitionEvent(selectedGlobalTransition ?? FsmEditor.SelectedTransition, fsmEvent);
            FsmEditor.EventManager.Reset();
            FsmEditor.EventManager.SelectEvent(fsmEvent, true);
            selectedGlobalTransition = null;
        }

        public static void ContextMenuSelectGlobalEvent(object userdata)
        {
            ContextMenuSelectEvent(userdata);
        }

        public void DeleteGlobalTransition(object userdata)
        {
            FsmTransition transition = userdata as FsmTransition;
            FsmEditor.Builder.DeleteGlobalTransition(transition);
        }

        private Vector2 DoAutoPan()
        {
            Vector2 deltaPos = new Vector2();
            float edgeScrollZone = FsmEditorSettings.EdgeScrollZone;
            float edgeScrollSpeed = FsmEditorSettings.EdgeScrollSpeed;
            float num3 = this.currentMousePos.x - FsmEditor.Selection.ScrollPosition.x;
            if ((num3 < edgeScrollZone) && (num3 > 0f))
            {
                float f = -(edgeScrollZone - num3) / edgeScrollZone;
                deltaPos.x = edgeScrollSpeed * Mathf.Pow(f, 3f);
            }
            else if ((num3 > (this.view.width - edgeScrollZone)) && (num3 < this.view.width))
            {
                float num5 = (num3 - (this.view.width - edgeScrollZone)) / edgeScrollZone;
                deltaPos.x = edgeScrollSpeed * Mathf.Pow(num5, 3f);
            }
            float num6 = this.currentMousePos.y - FsmEditor.Selection.ScrollPosition.y;
            if ((num6 < edgeScrollZone) && (num6 > 0f))
            {
                float num7 = -(edgeScrollZone - num6) / edgeScrollZone;
                deltaPos.y = edgeScrollSpeed * Mathf.Pow(num7, 3f);
            }
            else if ((num6 > (this.view.height - edgeScrollZone)) && (num6 < this.view.height))
            {
                float num8 = (num6 - (this.view.height - edgeScrollZone)) / edgeScrollZone;
                deltaPos.y = edgeScrollSpeed * Mathf.Pow(num8, 3f);
            }
            if (deltaPos.sqrMagnitude > 0f)
            {
                this.isAutoPanning = true;
            }
            deltaPos = (Vector2) (deltaPos * this.autoPanRampUp);
            if (deltaPos.sqrMagnitude > 0f)
            {
                ScrollView(deltaPos);
                if ((deltaPos.x <= 0f) && (deltaPos.y <= 0f))
                {
                    return deltaPos;
                }
                this.UpdateCanvasSize();
            }
            return deltaPos;
        }

        private void DoContextMenu()
        {
            if ((Event.current.type == EventType.ContextClick) && ((Event.current.mousePosition.x - FsmEditor.Selection.ScrollPosition.x) < this.view.width))
            {
                this.contextMenuPos = Event.current.mousePosition;
                //if (FsmEditor.SelectedDevice == null)
                {
                    if (FsmEditor.SelectedFsm == null)
                    {
                        if (Selection.activeGameObject != null)
                        {
                            GenerateAddFsmContextMenu().ShowAsContext();
                        }
                    }
                    else
                    {
                        this.GenerateContextMenu().ShowAsContext();
                    }
                }
                //else
                //{
                //}
                Event.current.Use();
            }
        }

        private void DoDragStates()
        {
            Vector2 vector = this.DoAutoPan();
            int num = 0;
            Vector2 vector2 = (this.currentMousePos - this.dragStartPos) + vector;
            foreach (FsmState state in FsmEditor.SelectedStates)
            {
                FsmBuilder.UpdateStatePosition(state, this.dragStartPositions[num] + vector2);
                if (Event.current.shift)
                {
                    this.ConstrainDragToAxis();
                }
                else
                {
                    this.dragConstraint = DragConstraint.None;
                }
                num++;
            }
            if (EditorGUI.actionKey)
            {
                SnapToGrid();
            }
        }

        private static void DoGlobalTransitionGUI(FsmState state)
        {
            List<FsmTransition> globalTransitions = FsmEditor.Builder.GetGlobalTransitions(state);
            if (globalTransitions.Count != 0)
            {
                Rect rect2 = new Rect(state.Position);
                rect2.height = globalTransitions.Count * 16f;
                Rect screenRect = rect2;
                screenRect.y -= screenRect.height + 32f;
                GUILayout.BeginArea(screenRect);
                GUI.backgroundColor = Color.white;
                foreach (FsmTransition transition in globalTransitions)
                {
                    GUILayout.Box(FsmEditorUtility.GetEventLabel(transition), FsmEditorStyles.GlobalTransitionBox, new GUILayoutOption[0]);
                }
                GUILayout.EndArea();
                Handles.color = Color.black;
                Handles.DrawLine(new Vector3(screenRect.x, screenRect.y + 1f), new Vector3(screenRect.x + screenRect.width, screenRect.y + 1f));
                DrawGlobalArrow(state, Color.black);
            }
        }

        internal GraphViewLevel viewLevel = GraphViewLevel.FSM;
        private void DoGraphGUI()
        {
            //Debug.Log(viewLevel);
            switch (viewLevel)
            {
                case GraphViewLevel.Sys:
                    DrawSysGraph();
                    break;
                case GraphViewLevel.Device:
                    if (FsmEditor.SelectedDevice != null)
                    {
                        DrawDeviceGraph();
                    }
                    break;
                case GraphViewLevel.Unit:
                    if (FsmEditor.SelectedUnit != null)
                    {
                        DrawUnitGraph();
                    }
                    break;
                case GraphViewLevel.FSM:
                    DoFSMGraphGUI();
                    break;
            }
        }

        private static void DrawUnitGraph()
        {
            foreach (PlayMakerFSM dev in FsmEditor.SelectedUnit.fsms)
            {
                DrawUnit(dev);
            }
        }

        private static void DrawUnit(PlayMakerFSM dev)
        {
            GUILayout.BeginArea(dev.Position);
            GUILayout.Box(new GUIContent(dev.name));
            GUILayout.EndArea();
        }

        private static void DrawDeviceGraph()
        {
            foreach (FsmUnit dev in FsmEditor.SelectedDevice.units)
            {
                DrawUnit(dev);
            }
        }

        private static void DrawSysGraph()
        {
            foreach (FsmDevice dev in FsmSys.Instance().devices)
            {
                DrawDevice(dev);
            }
        }

        private static void DrawUnit(FsmUnit dev)
        {
            GUILayout.BeginArea(dev.Position);
            GUILayout.Box(new GUIContent(dev.name));
            GUILayout.EndArea();
        }

        private static void DrawDevice(FsmDevice dev)
        {
            GUILayout.BeginArea(dev.Position);
            GUILayout.Box(new GUIContent(dev.name));
            GUILayout.EndArea();
        }

        private void DoFSMGraphGUI()
        {
            if (FsmEditor.SelectedFsm == null)
            {
                bool enabled = GUI.enabled;
                if (Selection.activeGameObject == null)
                {
                    if (FsmEditorSettings.EnableWatermarks)
                    {
                        GUILayout.Label("Select a GameObject", FsmEditorStyles.LargeWatermarkText, new GUILayoutOption[0]);
                    }
                    else
                    {
                        GUILayout.Label("Select a Game Object...", FsmEditorStyles.HintBox, new GUILayoutOption[0]);
                    }
                }
                else
                {
                    if (FsmEditorSettings.EnableWatermarks)
                    {
                        GUILayout.Label("Right-Click to Add FSM", FsmEditorStyles.LargeWatermarkText, new GUILayoutOption[0]);
                    }
                    else if (Selection.gameObjects.Length > 1)
                    {
                        GUILayout.Label("Right-Click to Add FSM to Selected Objects.", FsmEditorStyles.HintBox, new GUILayoutOption[0]);
                    }
                    else
                    {
                        GUILayout.Label("Right-Click to Add FSM to " + Selection.activeGameObject.name, FsmEditorStyles.HintBox, new GUILayoutOption[0]);
                    }
                    if ((Event.current.type == EventType.MouseDown) && EditorGUI.actionKey)
                    {
                        FsmBuilder.AddFsmToSelected();
                    }
                }
                GUI.enabled = enabled;
            }
            else
            {
                DrawStartArrow();
                if (!DebugFlow.Active && (GameStateTracker.CurrentState != GameState.Stopped))
                {
                    DrawStateHistory(FsmTime.RealtimeSinceStartup, 0.5f);
                }
                if (FsmEditorSettings.ShowCommentsInGraphView)
                {
                    foreach (FsmState state in FsmEditor.SelectedFsm.States)
                    {
                        DrawStateDescription(state);
                    }
                }
                foreach (FsmState state2 in FsmEditor.SelectedFsm.States)
                {
                    state2.Fsm = FsmEditor.SelectedFsm;
                    DoStateGUI(state2);
                }
                foreach (DrawState state3 in Enum.GetValues(typeof(DrawState)))
                {
                    foreach (FsmState state4 in FsmEditor.SelectedFsm.States)
                    {
                        for (int i = 0; i < state4.Transitions.Length; i++)
                        {
                            this.DoLinkGUI(state4, i, state3);
                        }
                    }
                }
                foreach (FsmState state5 in FsmEditor.SelectedFsm.States)
                {
                    DoGlobalTransitionGUI(state5);
                }
                if (GameStateTracker.CurrentState != GameState.Stopped)
                {
                    if (DebugFlow.Active)
                    {
                        DrawLastTransition();
                    }
                    else
                    {
                        DrawTransitionHistory(FsmTime.RealtimeSinceStartup, 0.5f);
                    }
                }
                if (((this.draggingMode == DraggingMode.Selection) && (Event.current.type == EventType.Repaint)) && this.dragStarted)
                {
                    this.DrawSelectionRect();
                }
                if (!FsmEditorSettings.EnableWatermarks && FsmEditorSettings.ShowCommentsInGraphView)
                {
                    this.DrawFsmDescription(FsmEditor.SelectedFsm);
                }
                this.DrawFsmHelUrlButton(FsmEditor.SelectedFsm);
            }
        }

        private void DoLinkGUI(FsmState fromState, int i, DrawState drawStateFilter)
        {
            FsmTransition transition = fromState.Transitions[i];
            DrawState drawState = FsmDrawState.GetFsmTransitionDrawState(FsmEditor.SelectedFsm, transition, FsmEditor.SelectedTransition == transition);
            if (drawState == drawStateFilter)
            {
                FsmState state = FsmEditor.SelectedFsm.GetState(transition.ToState);
                if ((FsmEditor.Selection.Contains(transition) && (this.draggingMode == DraggingMode.Transition)) && this.dragStarted)
                {
                    state = this.dummyDraggingState;
                    if (this.mouseOverState != null)
                    {
                        this.dummyDraggingState.Position = this.mouseOverState.Position;
                    }
                    else
                    {
                        FsmBuilder.UpdateStatePosition(this.dummyDraggingState, this.currentMousePos);
                        Rect rect = new Rect(this.dummyDraggingState.Position);
                        rect.y -= 8f;
                        rect.width = 0f;
                        this.dummyDraggingState.Position = rect;
                    }
                }
                if (Event.current.type == EventType.Repaint)
                {
                    Color color = GetLinkColor(fromState, transition, drawState);
                    float width = FsmEditorStyles.LinkWidths[(int) drawState];
                    DrawLink(fromState, state, i, color, width);
                }
            }
        }

        private static void DoStateGUI(FsmState state)
        {
            if (Event.current.type == EventType.Repaint)
            {
                if (state.Position.width.Equals((float) 0f))
                {
                    FsmBuilder.UpdateStateSize(state);
                }
                DrawShadow(state.Position);
                bool selected = FsmEditor.Selection.Contains(state);
                DrawState normal = FsmDrawState.GetFsmStateDrawState(FsmEditor.SelectedFsm, state, selected);
                if (DebugFlow.Active)
                {
                    if (normal == DrawState.Paused)
                    {
                        normal = DrawState.Normal;
                    }
                    if (selected)
                    {
                        normal = DrawState.Selected;
                    }
                    if (state == DebugFlow.DebugState)
                    {
                        normal = DrawState.Paused;
                    }
                }
                if (normal != DrawState.Normal)
                {
                    DrawStateHighlight(state.Position, FsmEditorStyles.HighlightColors[(int) normal]);
                }
                FsmEditorStyles.StateBox.Draw(state.Position, false, false, false, false);
                GUI.backgroundColor = Fsm.StateColors[state.ColorIndex];
                FsmEditorStyles.StateTitleBox.Draw(state.Position, new GUIContent(state.Name, state.Name), false, false, false, false);
                for (int i = 0; i < state.Transitions.Length; i++)
                {
                    FsmTransition transition = state.Transitions[i];
                    Rect position = new Rect(state.Position);
                    position.y += 16f * (i + 1);
                    if (transition == FsmEditor.SelectedTransition)
                    {
                        GUI.backgroundColor = Color.white;
                        GUI.contentColor = Color.white;
                        FsmEditorStyles.TransitionBoxSelected.Draw(position, FsmEditorUtility.GetEventLabel(transition), false, false, false, false);
                    }
                    else
                    {
                        GUI.backgroundColor = GetTransitionBoxColor(state, transition);
                        GUI.contentColor = GetTransitionContentColor(state, transition);
                        FsmEditorStyles.TransitionBox.Draw(position, FsmEditorUtility.GetEventLabel(transition), false, false, false, false);
                    }
                }
                GUI.backgroundColor = Color.white;
                GUI.contentColor = Color.white;
                if (state.IsBreakpoint)
                {
                    DrawBreakpoint(state);
                }
                if (FsmErrorChecker.StateHasErrors(state))
                {
                    DrawStateError(state);
                }
            }
        }

        public static void DrawArrowHead(Texture leftArrow, Vector2 pos, Color color, bool flipTexture)
        {
            Color color2 = GUI.color;
            GUI.color = color;
            if (!flipTexture)
            {
                GUI.DrawTexture(new Rect(pos.x, pos.y - (leftArrow.height * 0.5f), (float) leftArrow.width, (float) leftArrow.height), leftArrow);
            }
            else
            {
                Matrix4x4 matrix = GUI.matrix;
                GUIUtility.ScaleAroundPivot(new Vector2(-1f, 1f), pos);
                GUI.DrawTexture(new Rect(pos.x, pos.y - (leftArrow.height * 0.5f), (float) leftArrow.width, (float) leftArrow.height), leftArrow);
                GUI.matrix = matrix;
            }
            GUI.color = color2;
        }

        private void DrawBackground(Rect area)
        {
            FsmEditorStyles.Background.Draw(area, false, false, false, false);
            if (FsmEditorSettings.EnableWatermarks)
            {
                this.DrawWatermark();
            }
        }

        private static void DrawBreakpoint(FsmState state)
        {
            float width = FsmEditorStyles.BreakpointOff.normal.background.width;
            float height = FsmEditorStyles.BreakpointOff.normal.background.height;
            Rect position = state.Position;
            position.width = width;
            position.height = height;
            if (FsmEditorSettings.BreakpointsEnabled)
            {
                FsmEditorStyles.BreakpointOn.Draw(position, false, false, false, false);
            }
            else
            {
                FsmEditorStyles.BreakpointOff.Draw(position, false, false, false, false);
            }
        }

        private void DrawCanvas()
        {
            if (FsmEditor.SelectedFsm != null)
            {
                GUILayout.Box(GUIContent.none, GUIStyle.none, new GUILayoutOption[] { GUILayout.MinWidth(this.canvasSize.x), GUILayout.MinHeight(this.canvasSize.y) });
                if (this.takingScreenshot)
                {
                    Texture watermarkTexture = FsmEditorUtility.GetWatermarkTexture(FsmEditor.SelectedFsmComponent);
                    if (watermarkTexture != null)
                    {
                        Color color = GUI.color;
                        GUI.color = FsmEditorStyles.WatermarkTint;
                        GUI.Box(new Rect(0f, 0f, (float) this.screenshotWidth, (float) this.screenshotHeight), watermarkTexture, FsmEditorStyles.Watermark);
                        GUI.color = color;
                    }
                }
            }
        }

        private void DrawFrame(Rect area)
        {
            DrawState drawState = FsmDrawState.GetDrawState(FsmEditor.SelectedFsm);
            Color color = GUI.color;
            GUI.color = FsmEditorStyles.HighlightColors[(int) drawState];
            FsmEditorStyles.InnerGlowBox.Draw(area, false, false, false, false);
            GUI.color = color;
        }

        private void DrawFsmDescription(Fsm fsm)
        {
            if ((fsm != null) && (!this.takingScreenshot || ((this.tileOffsetX + this.tileOffsetY) <= 0)))
            {
                Rect position = new Rect();
                if (!string.IsNullOrEmpty(fsm.Description))
                {
                    if (FsmEditorSettings.EnableWatermarks)
                    {
                        position.height = FsmEditorStyles.SmallWatermarkText.CalcHeight(new GUIContent(fsm.Description), 200f);
                        GUI.Box(new Rect(this.view.x + 5f, this.view.y + 40f, 200f, position.height), fsm.Description, FsmEditorStyles.SmallWatermarkText);
                        position.height += this.view.y + 40f;
                    }
                    else
                    {
                        position = GUILayoutUtility.GetRect(new GUIContent(fsm.Description), FsmEditorStyles.CommentBox, new GUILayoutOption[] { GUILayout.MaxWidth(200f) });
                        position.x = FsmEditor.Selection.ScrollPosition.x + 10f;
                        position.y = FsmEditor.Selection.ScrollPosition.y + 10f;
                        GUI.Box(position, fsm.Description, FsmEditorStyles.CommentBox);
                    }
                }
            }
        }

        private void DrawFsmHelUrlButton(Fsm fsm)
        {
            if (!string.IsNullOrEmpty(fsm.DocUrl))
            {
                Rect position = new Rect((this.view.x + this.view.width) - 32f, 10f, 18f, 18f);
                FsmEditorStyles.HelpButton.tooltip = "Fsm Docs";
                if (GUI.Button(position, FsmEditorStyles.HelpButton, GUIStyle.none))
                {
                    Application.OpenURL(fsm.DocUrl);
                }
            }
        }

        private void DrawGameStateIcon()
        {
            if ((FsmEditor.SelectedFsm != null) && FsmEditor.SelectedFsm.Owner.enabled)
            {
                float gameStateIconSize = FsmEditorSettings.GameStateIconSize;
                Rect position = new Rect(10f, ((this.view.height - FsmEditorStyles.HorizontalScrollBarHeight) - EditorStyles.toolbar.fixedHeight) - gameStateIconSize, gameStateIconSize, gameStateIconSize + 20f);
                if (FsmEditor.SelectedFsm.Active)
                {
                    Texture2D image = FsmEditorStyles.GetGameStateIcons()[(int) GameStateTracker.CurrentState];
                    if ((image != null) && GUI.Button(position, image, GUIStyle.none))
                    {
                        switch (GameStateTracker.CurrentState)
                        {
                            case GameState.Running:
                                EditorApplication.isPaused = true;
                                break;

                            case GameState.Break:
                            case GameState.Error:
                                FsmEditor.GotoBreakpoint();
                                break;

                            case GameState.Paused:
                                EditorApplication.isPaused = false;
                                break;
                        }
                    }
                }
                if (FsmEditorSettings.EnableWatermarks)
                {
                    Color color = GUI.color;
                    DrawState drawState = FsmDrawState.GetDrawState(FsmEditor.SelectedFsm);
                    GUI.color = FsmEditorStyles.HighlightColors[(int) drawState];
                    string selectedStateName = FsmEditor.SelectedStateName;
                    position.y -= 3f;
                    position.width = this.view.width - position.width;
                    if (!FsmEditor.SelectedFsm.Active)
                    {
                        position.x = 5f;
                        selectedStateName = "[NOT ACTIVE]";
                    }
                    else
                    {
                        position.x = 45f;
                        if (DebugFlow.ActiveAndScrubbing)
                        {
                            selectedStateName = (DebugFlow.DebugState != null) ? DebugFlow.DebugState.Name : " [None]";
                        }
                        else
                        {
                            selectedStateName = FsmEditor.SelectedFsm.ActiveStateName;
                        }
                    }
                    GUI.Box(position, selectedStateName, FsmEditorStyles.LargeText);
                    GUI.color = color;
                }
            }
        }

        private static void DrawGlobalArrow(FsmState state, Color color)
        {
            Rect rect2 = new Rect(state.Position);
            rect2.height = FsmEditorStyles.GlobalArrow.height;
            rect2.width = FsmEditorStyles.GlobalArrow.width;
            Rect position = rect2;
            position.y -= position.height;
            position.x = (position.x + (state.Position.width * 0.5f)) - (position.width * 0.5f);
            FsmEditorUtility.DrawTexture(position, FsmEditorStyles.GlobalArrow, color);
        }

        private static void DrawHintBox(Rect area)
        {
            if (FsmEditorSettings.ShowHints)
            {
                if (FsmEditor.SelectedFsm != null)
                {
                    Rect rect3 = new Rect();
                    rect3.x = area.xMax - 300f;
                    rect3.y = area.yMax - 190f;
                    rect3.width = 280f;
                    rect3.height = 170f;
                    Rect source = rect3;
                    Rect position = new Rect(source);
                    position.x += 140f;
                    GUI.Box(source, "Shortcut Hints:\nAdd State:\nAdd Transition:\nAdd Transition State:\nQuick Delete:\nSnap To Grid:\nConstrain Drag:\nSelect Start State:\nFollow Transition:\nLock Link Direction:\nUnlock Link Direction:\nCycle Link Style:", FsmEditorStyles.HintBox);
                    GUI.Box(position, (Application.platform == RuntimePlatform.OSXEditor) ? "F1 Show/Hide\nCmd Click Canvas\nCmd Click State\nCmd Drag Transition\nCmd Shift Click\nCmd Drag States\nShift Drag States\nHome\nAlt Click Transition\nCmd Left/Right\nCmd Down\nCmd Up" : "F1 Show/Hide\nCtrl Click Canvas\nCtrl Click State\nCtrl Drag Transition\nCtrl Shift Click\nCtrl Drag States\nShift Drag States\nHome\nAlt Click Transition\nCtrl Left/Right\nCtrl Down\nCtrl Up", FsmEditorStyles.HintBoxTextOnly);
                }
                else
                {
                    Rect rect5 = new Rect();
                    rect5.x = area.xMax - 300f;
                    rect5.y = area.yMax - 70f;
                    rect5.width = 280f;
                    rect5.height = 50f;
                    Rect rect4 = rect5;
                    GUI.Box(rect4, "1. Select a GameObject in any view.\n2. Right click in this view to add an FSM.\n3. Build an FSM to control the GameObject.", FsmEditorStyles.HintBox);
                }
            }
        }

        private static void DrawLastTransition()
        {
            FsmLogEntry lastTransition = DebugFlow.GetLastTransition();
            if (lastTransition != null)
            {
                FsmTransition transition = lastTransition.Transition;
                if (transition != null)
                {
                    FsmState state = lastTransition.State;
                    FsmState toState = FsmEditor.SelectedFsm.GetState(transition.ToState);
                    Color color = FsmEditorStyles.HighlightColors[5];
                    float width = FsmEditorStyles.LinkWidths[2];
                    if (state != null)
                    {
                        int transitionIndex = FsmEditor.Builder.GetTransitionIndex(state, transition);
                        DrawLink(state, toState, transitionIndex, color, width);
                    }
                    else
                    {
                        DrawGlobalArrow(toState, color);
                    }
                }
            }
        }

        private static void DrawLink(FsmState fromState, FsmState toState, int i, Color color, float width)
        {
            if (toState != null)
            {
                FsmTransition transition = fromState.Transitions[i];
                GraphViewLinkStyle graphViewLinkStyle = FsmEditorSettings.GraphViewLinkStyle;
                switch (transition.LinkStyle)
                {
                    case FsmTransition.CustomLinkStyle.Bezier:
                        graphViewLinkStyle = GraphViewLinkStyle.BezierLinks;
                        break;

                    case FsmTransition.CustomLinkStyle.Circuit:
                        graphViewLinkStyle = GraphViewLinkStyle.CircuitLinks;
                        break;
                }
                switch (graphViewLinkStyle)
                {
                    case GraphViewLinkStyle.BezierLinks:
                        BezierLink.Draw(fromState, toState, i, color, width, FsmEditorStyles.LeftArrow, FsmEditorStyles.RightArrow);
                        return;

                    case GraphViewLinkStyle.CircuitLinks:
                        CircuitLink.Draw(fromState, toState, i, color, width, FsmEditorStyles.LeftArrow, FsmEditorStyles.RightArrow);
                        return;
                }
            }
        }

        private void DrawSelectionRect()
        {
            float left = Mathf.Min(this.dragStartPos.x, this.currentMousePos.x);
            float top = Mathf.Min(this.dragStartPos.y, this.currentMousePos.y);
            float width = Mathf.Abs((float) (this.currentMousePos.x - this.dragStartPos.x));
            float height = Mathf.Abs((float) (this.currentMousePos.y - this.dragStartPos.y));
            Rect position = new Rect(left, top, width, height);
            FsmEditorStyles.SelectionRect.Draw(position, false, false, false, false);
        }

        private static void DrawShadow(Rect rect)
        {
            Color color = GUI.color;
            GUI.color = Color.black;
            FsmEditorStyles.DropShadowBox.Draw(rect, false, false, false, false);
            GUI.color = color;
        }

        private static void DrawStartArrow()
        {
            FsmState startState = FsmEditor.Builder.GetStartState();
            if (startState != null)
            {
                List<FsmTransition> globalTransitions = FsmEditor.Builder.GetGlobalTransitions(startState);
                Rect rect2 = new Rect(startState.Position);
                rect2.height = 16f;
                Rect position = rect2;
                position.y -= ((globalTransitions.Count * 16f) + 16f) + 31f;
                GUI.backgroundColor = Color.white;
                GUI.Box(position, "START", FsmEditorStyles.StartTransitionBox);
                if (globalTransitions.Count == 0)
                {
                    DrawGlobalArrow(startState, Color.black);
                }
            }
        }

        private static void DrawStateDescription(FsmState state)
        {
            if (!string.IsNullOrEmpty(state.Description))
            {
                Rect position = GUILayoutUtility.GetRect(new GUIContent(state.Description), FsmEditorStyles.CommentBox, new GUILayoutOption[] { GUILayout.MaxWidth(state.Position.width) });
                position.x = state.Position.x;
                position.y = state.Position.yMax + 5f;
                GUI.Box(position, state.Description, FsmEditorStyles.CommentBox);
            }
        }

        private static void DrawStateError(FsmState state)
        {
            Rect position = state.Position;
            position.y -= 6f;
            position.x -= 5f;
            position.width = position.height = 14f;
            GUI.DrawTexture(position, FsmEditorStyles.StateErrorIcon);
        }

        private static void DrawStateHighlight(Rect rect, Color color)
        {
            Color color2 = GUI.color;
            GUI.color = color;
            FsmEditorStyles.SelectionBox.Draw(rect, false, false, false, false);
            GUI.color = color2;
        }

        private static void DrawStateHistory(float currentTime, float timeWindow)
        {
            if ((Event.current.type == EventType.Repaint) && EditorApplication.isPlaying)
            {
                float num = currentTime - timeWindow;
                foreach (FsmLogEntry entry in FsmEditor.SelectedFsm.MyLog.Entries)
                {
                    if (entry.Time > currentTime)
                    {
                        break;
                    }
                    if (((entry.Time >= num) && ((entry.LogType == FsmLogType.EnterState) || (entry.LogType == FsmLogType.ExitState))) && (entry.State != null))
                    {
                        Color color = FsmEditorStyles.HighlightColors[2];
                        color.a = (entry.Time - num) / timeWindow;
                        DrawStateHighlight(entry.State.Position, color);
                    }
                }
            }
        }

        private static void DrawTransitionHistory(float currentTime, float timeWindow)
        {
            if ((Event.current.type == EventType.Repaint) && EditorApplication.isPlaying)
            {
                float num = currentTime - timeWindow;
                Color color = !EditorApplication.isPaused ? FsmEditorStyles.HighlightColors[2] : FsmEditorStyles.HighlightColors[5];
                float width = FsmEditorStyles.LinkWidths[2];
                foreach (FsmLogEntry entry in FsmEditor.SelectedFsm.MyLog.Entries)
                {
                    if ((entry.LogType == FsmLogType.Transition) && (entry.Time >= num))
                    {
                        if (entry.Time > currentTime)
                        {
                            break;
                        }
                        FsmTransition transition = entry.Transition;
                        if (transition != null)
                        {
                            FsmState state = entry.State;
                            FsmState toState = FsmEditor.SelectedFsm.GetState(transition.ToState);
                            color.a = (entry.Time - num) / timeWindow;
                            if (state != null)
                            {
                                int transitionIndex = FsmEditor.Builder.GetTransitionIndex(state, transition);
                                DrawLink(state, toState, transitionIndex, color, width);
                            }
                            else
                            {
                                DrawGlobalArrow(toState, color);
                            }
                        }
                    }
                }
            }
        }

        private void DrawWatermark()
        {
            Texture defaultWatermark = FsmEditorStyles.DefaultWatermark;
            if (!this.takingScreenshot || ((this.tileOffsetX <= 0) && (this.tileOffsetY <= 0)))
            {
                if (FsmEditor.SelectedFsm != null)
                {
                    switch (viewLevel)
                    {
                        case GraphViewLevel.Sys:
                            GUI.Box(new Rect(this.view.x + 5f, this.view.y + 5f, this.view.width - 5f, 100f), "系统结构图", FsmEditorStyles.LargeWatermarkText);
                            break;
                        case GraphViewLevel.Device:
                            GUI.Box(new Rect(this.view.x + 5f, this.view.y + 5f, this.view.width - 5f, 100f), "设备结构图", FsmEditorStyles.LargeWatermarkText);
                            break;
                        case GraphViewLevel.Unit:
                            GUI.Box(new Rect(this.view.x + 5f, this.view.y + 5f, this.view.width - 5f, 100f), "元件结构图", FsmEditorStyles.LargeWatermarkText);
                            break;
                        case GraphViewLevel.FSM:
                            GUI.Box(new Rect(this.view.x + 5f, this.view.y + 5f, this.view.width - 5f, 100f), FsmEditorUtility.GetFullFsmLabel(FsmEditor.SelectedFsm), FsmEditorStyles.LargeWatermarkText);
                            break;
                    }
                    defaultWatermark = FsmEditorUtility.GetWatermarkTexture(FsmEditor.SelectedFsmComponent);
                }
                if ((defaultWatermark != null) && !this.takingScreenshot)
                {
                    Color color = GUI.color;
                    GUI.color = FsmEditorStyles.WatermarkTint;
                    GUI.Box(new Rect(this.view.x, this.view.y, this.view.width, this.view.height - EditorStyles.toolbar.fixedHeight), defaultWatermark, FsmEditorStyles.Watermark);
                    GUI.color = color;
                }
            }
        }

        public void FrameState(FsmState state)
        {
            if (state != null)
            {
                this.FrameState(state, true);
            }
        }

        public void FrameState(FsmState state, bool smooth)
        {
            if (state != null)
            {
                Vector2 vector2 = new Vector2();
                vector2.x = state.Position.x + (state.Position.width * 0.5f);
                vector2.y = state.Position.y + state.Position.height;
                Vector2 pos = vector2;
                if (smooth)
                {
                    this.StartPanToPosition(pos);
                }
                else
                {
                    this.SetScrollPosition(pos);
                }
            }
        }

        private static GenericMenu GenerateDeviceContextMenu()
        {
            GenericMenu menu = new GenericMenu();
            menu.AddItem(new GUIContent("Add Device"), false, new GenericMenu.MenuFunction(FsmBuilder.AddDeviceToSelected));
            return menu;
        }

        private static GenericMenu GenerateAddFsmContextMenu()
        {
            GenericMenu menu = new GenericMenu();
            menu.AddItem(new GUIContent("Add FSM"), false, new GenericMenu.MenuFunction(FsmBuilder.AddFsmToSelected));
            if (FsmEditor.Builder.CanPaste())
            {
                menu.AddItem(new GUIContent("Paste FSM"), false, new GenericMenu.MenuFunction(EditorCommands.PasteFsm));
            }
            else
            {
                menu.AddDisabledItem(new GUIContent("Paste FSM"));
            }
            foreach (string str in FsmEditorUtility.TemplateCategories)
            {
                foreach (KeyValuePair<FsmTemplate, string> pair in FsmEditorUtility.TemplateCategoryLookup)
                {
                    if (pair.Value == str)
                    {
                        FsmTemplate key = pair.Key;
                        menu.AddItem(new GUIContent("Add Template/" + str + "/" + key.name), false, new GenericMenu.MenuFunction2(EditorCommands.AddTemplateToSelected), key);
                    }
                }
            }
            if (FsmEditorUtility.TemplateList.Count == 0)
            {
                menu.AddDisabledItem(new GUIContent("Add Template"));
            }
            return menu;
        }

        private GenericMenu GenerateContextMenu()
        {
            GenericMenu menu = new GenericMenu();
            if (this.mouseOverGlobalTransition != null)
            {
                bool flag;
                selectedGlobalTransition = this.mouseOverGlobalTransition;
                foreach (FsmEvent event2 in FsmEditor.SelectedFsm.Events)
                {
                    flag = event2 == selectedGlobalTransition.FsmEvent;
                    menu.AddItem(new GUIContent("Transition Event/" + event2.Name), flag, new GenericMenu.MenuFunction2(FsmGraphView.ContextMenuSelectEvent), event2);
                }
                FsmEvent fsmEvent = FsmEvent.GetFsmEvent("FINISHED");
                flag = selectedGlobalTransition.FsmEvent == fsmEvent;
                menu.AddItem(new GUIContent("Transition Event/FINISHED"), flag, new GenericMenu.MenuFunction2(FsmGraphView.ContextMenuSelectEvent), fsmEvent);
                foreach (FsmEvent event4 in FsmEvent.EventList)
                {
                    if (!event4.IsSystemEvent)
                    {
                        flag = event4 == selectedGlobalTransition.FsmEvent;
                        menu.AddItem(new GUIContent("Transition Event/Custom Events/" + event4.Name), flag, new GenericMenu.MenuFunction2(FsmGraphView.ContextMenuSelectEvent), event4);
                    }
                }
                foreach (FsmEvent event5 in FsmEvent.EventList)
                {
                    if (event5.IsGlobal)
                    {
                        flag = event5 == selectedGlobalTransition.FsmEvent;
                        menu.AddItem(new GUIContent("Transition Event/Global Events/" + event5.Name), flag, new GenericMenu.MenuFunction2(FsmGraphView.ContextMenuSelectEvent), event5);
                    }
                }
                foreach (FsmEvent event6 in FsmEvent.EventList)
                {
                    if (event6.IsSystemEvent && (event6 != FsmEvent.Finished))
                    {
                        flag = event6 == selectedGlobalTransition.FsmEvent;
                        menu.AddItem(new GUIContent("Transition Event/" + event6.Path + event6.Name), flag, new GenericMenu.MenuFunction2(FsmGraphView.ContextMenuSelectEvent), event6);
                    }
                }
                menu.AddSeparator("");
                menu.AddItem(new GUIContent("Clear Transition Event"), false, new GenericMenu.MenuFunction2(FsmGraphView.ContextMenuSelectEvent), null);
                menu.AddItem(new GUIContent("Delete Transition"), false, new GenericMenu.MenuFunction2(this.DeleteGlobalTransition), this.mouseOverGlobalTransition);
                return menu;
            }
            if (FsmEditor.SelectedTransition != null)
            {
                bool flag2;
                foreach (FsmEvent event7 in FsmEditor.SelectedFsm.Events)
                {
                    flag2 = event7 == FsmEditor.SelectedTransition.FsmEvent;
                    menu.AddItem(new GUIContent("Transition Event/" + event7.Name), flag2, new GenericMenu.MenuFunction2(FsmGraphView.ContextMenuSelectEvent), event7);
                }
                FsmEvent userData = FsmEvent.GetFsmEvent("FINISHED");
                flag2 = FsmEditor.SelectedTransition.FsmEvent == userData;
                menu.AddItem(new GUIContent("Transition Event/FINISHED"), flag2, new GenericMenu.MenuFunction2(FsmGraphView.ContextMenuSelectEvent), userData);
                foreach (FsmEvent event9 in FsmEvent.EventList)
                {
                    if (!event9.IsSystemEvent)
                    {
                        flag2 = event9 == FsmEditor.SelectedTransition.FsmEvent;
                        menu.AddItem(new GUIContent("Transition Event/Custom Events/" + event9.Name), flag2, new GenericMenu.MenuFunction2(FsmGraphView.ContextMenuSelectEvent), event9);
                    }
                }
                foreach (FsmEvent event10 in FsmEvent.EventList)
                {
                    if (event10.IsGlobal)
                    {
                        flag2 = event10 == FsmEditor.SelectedTransition.FsmEvent;
                        menu.AddItem(new GUIContent("Transition Event/Global Events/" + event10.Name), flag2, new GenericMenu.MenuFunction2(FsmGraphView.ContextMenuSelectEvent), event10);
                    }
                }
                foreach (FsmEvent event11 in FsmEvent.EventList)
                {
                    if (event11.IsSystemEvent && (event11 != FsmEvent.Finished))
                    {
                        flag2 = event11 == FsmEditor.SelectedTransition.FsmEvent;
                        menu.AddItem(new GUIContent("Transition Event/" + event11.Path + event11.Name), flag2, new GenericMenu.MenuFunction2(FsmGraphView.ContextMenuSelectEvent), event11);
                    }
                }
                menu.AddSeparator("");
                menu.AddItem(new GUIContent("Link Style/Default"), FsmEditor.SelectedTransition.LinkStyle == FsmTransition.CustomLinkStyle.Default, new GenericMenu.MenuFunction2(EditorCommands.SetTransitionLinkStyle), FsmTransition.CustomLinkStyle.Default);
                menu.AddItem(new GUIContent("Link Style/Bezier"), FsmEditor.SelectedTransition.LinkStyle == FsmTransition.CustomLinkStyle.Bezier, new GenericMenu.MenuFunction2(EditorCommands.SetTransitionLinkStyle), FsmTransition.CustomLinkStyle.Bezier);
                menu.AddItem(new GUIContent("Link Style/Circuit"), FsmEditor.SelectedTransition.LinkStyle == FsmTransition.CustomLinkStyle.Circuit, new GenericMenu.MenuFunction2(EditorCommands.SetTransitionLinkStyle), FsmTransition.CustomLinkStyle.Circuit);
                menu.AddItem(new GUIContent("Link Direction/Auto Direction"), FsmEditor.SelectedTransition.LinkConstraint == FsmTransition.CustomLinkConstraint.None, new GenericMenu.MenuFunction2(EditorCommands.SetTransitionLinkConstraint), FsmTransition.CustomLinkConstraint.None);
                menu.AddItem(new GUIContent("Link Direction/Lock To Left"), FsmEditor.SelectedTransition.LinkConstraint == FsmTransition.CustomLinkConstraint.LockLeft, new GenericMenu.MenuFunction2(EditorCommands.SetTransitionLinkConstraint), FsmTransition.CustomLinkConstraint.LockLeft);
                menu.AddItem(new GUIContent("Link Direction/Lock To Right"), FsmEditor.SelectedTransition.LinkConstraint == FsmTransition.CustomLinkConstraint.LockRight, new GenericMenu.MenuFunction2(EditorCommands.SetTransitionLinkConstraint), FsmTransition.CustomLinkConstraint.LockRight);
                int num = 0;
                foreach (string str in FsmEditorUtility.StateColorNames)
                {
                    menu.AddItem(new GUIContent("Link Color/" + str), FsmEditor.SelectedTransition.ColorIndex == num, new GenericMenu.MenuFunction2(EditorCommands.SetTransitionColorIndex), num);
                    num++;
                }
                menu.AddSeparator("");
                menu.AddItem(new GUIContent("Clear Transition Event"), flag2, new GenericMenu.MenuFunction2(FsmGraphView.ContextMenuSelectEvent), null);
                menu.AddItem(new GUIContent("Delete Transition"), false, new GenericMenu.MenuFunction(EditorCommands.DeleteSelectedTransition));
                return menu;
            }
            if (FsmEditor.SelectedState != null)
            {
                menu.AddItem(new GUIContent("Add Transition"), false, new GenericMenu.MenuFunction(EditorCommands.AddTransitionToSelectedState));
                menu.AddItem(new GUIContent("Add Global Transition"), false, new GenericMenu.MenuFunction(EditorCommands.AddGlobalTransitionToSelectedState));
                menu.AddSeparator("");
                if (FsmEditor.Builder.IsStartState(FsmEditor.SelectedState))
                {
                    menu.AddDisabledItem(new GUIContent("Set as Start State"));
                }
                else
                {
                    menu.AddItem(new GUIContent("Set as Start State"), false, new GenericMenu.MenuFunction(EditorCommands.SetSelectedStateAsStartState));
                }
                int num2 = 0;
                foreach (string str2 in FsmEditorUtility.StateColorNames)
                {
                    menu.AddItem(new GUIContent("Set Color/" + str2), FsmEditor.SelectedState.ColorIndex == num2, new GenericMenu.MenuFunction2(EditorCommands.SetSelectedStatesColorIndex), num2);
                    num2++;
                }
                menu.AddSeparator("");
                if (FsmEditor.SelectedStates.Count > 0)
                {
                    menu.AddItem(new GUIContent("Copy States"), false, new GenericMenu.MenuFunction(EditorCommands.CopyStateSelection));
                }
                else
                {
                    menu.AddDisabledItem(new GUIContent("Copy States"));
                }
                menu.AddItem(new GUIContent("Save Template"), false, new GenericMenu.MenuFunction(EditorCommands.SaveSelectionAsTemplate));
                menu.AddItem(new GUIContent("Delete States"), false, new GenericMenu.MenuFunction(EditorCommands.DeleteMultiSelection));
                menu.AddSeparator("");
                menu.AddItem(new GUIContent("Toggle Breakpoint"), false, new GenericMenu.MenuFunction(EditorCommands.ToggleBreakpointOnSelectedState));
                return menu;
            }
            menu.AddItem(new GUIContent("Add New Device"), false, new GenericMenu.MenuFunction(this.AddDevice));
            menu.AddItem(new GUIContent("Add New Unit"), false, new GenericMenu.MenuFunction(this.AddUnit));
            menu.AddItem(new GUIContent("Add New FSM"), false, new GenericMenu.MenuFunction(this.AddFSM));
            menu.AddItem(new GUIContent("Add New State"), false, new GenericMenu.MenuFunction(this.AddState));
            if (FsmEditor.Builder.CanPaste())
            {
                menu.AddItem(new GUIContent("Paste States"), false, new GenericMenu.MenuFunction(this.PasteStates));
            }
            else
            {
                menu.AddDisabledItem(new GUIContent("Paste States"));
            }
            foreach (string str3 in FsmEditorUtility.TemplateCategories)
            {
                foreach (KeyValuePair<FsmTemplate, string> pair in FsmEditorUtility.TemplateCategoryLookup)
                {
                    if (pair.Value == str3)
                    {
                        FsmTemplate key = pair.Key;
                        menu.AddItem(new GUIContent("Paste Template/" + str3 + "/" + key.name), false, new GenericMenu.MenuFunction2(this.PasteTemplate), key);
                    }
                }
            }
            if (FsmEditorUtility.TemplateList.Count == 0)
            {
                menu.AddDisabledItem(new GUIContent("Paste Template"));
            }
            menu.AddSeparator("");
            menu.AddItem(new GUIContent("Copy FSM"), false, new GenericMenu.MenuFunction(EditorCommands.CopyFsm));
            menu.AddItem(new GUIContent("Save Template"), false, new GenericMenu.MenuFunction(EditorCommands.SaveFsmAsTemplate));
            menu.AddSeparator("");
            menu.AddItem(new GUIContent("Set Watermark"), false, new GenericMenu.MenuFunction(EditorCommands.ChooseWatermark));
            menu.AddItem(new GUIContent("Save Screenshot"), false, new GenericMenu.MenuFunction(this.TakeScreenshot));
            menu.AddSeparator("");
            if (Selection.activeGameObject != null)
            {
                menu.AddItem(new GUIContent("Add FSM Component/New FSM"), false, new GenericMenu.MenuFunction(FsmBuilder.AddFsmToSelected));
                if (FsmEditor.Builder.CanPaste())
                {
                    menu.AddItem(new GUIContent("Add FSM Component/Paste FSM"), false, new GenericMenu.MenuFunction(EditorCommands.PasteFsm));
                }
                else
                {
                    menu.AddDisabledItem(new GUIContent("Add FSM Component/Paste FSM"));
                }
                foreach (string str4 in FsmEditorUtility.TemplateCategories)
                {
                    foreach (KeyValuePair<FsmTemplate, string> pair2 in FsmEditorUtility.TemplateCategoryLookup)
                    {
                        if (pair2.Value == str4)
                        {
                            FsmTemplate template2 = pair2.Key;
                            menu.AddItem(new GUIContent("Add FSM Component/Use Template/" + str4 + "/" + template2.name), false, new GenericMenu.MenuFunction2(EditorCommands.AddTemplate), template2);
                        }
                    }
                }
                if (FsmEditorUtility.TemplateList.Count == 0)
                {
                    menu.AddDisabledItem(new GUIContent("Add FSM Component/Add Template"));
                }
            }
            else
            {
                menu.AddDisabledItem(new GUIContent("Add FSM Component"));
            }
            menu.AddItem(new GUIContent("Remove FSM Component"), false, new GenericMenu.MenuFunction(EditorCommands.RemoveFsmComponent));
            return menu;
        }

        private static Color GetLinkColor(FsmState fromState, FsmTransition transition, DrawState drawState)
        {
            if (drawState == DrawState.Normal)
            {
                if (transition.ColorIndex > 0)
                {
                    return FsmEditorStyles.CustomLinkColors[transition.ColorIndex];
                }
                if (FsmEditorSettings.ColorLinks && (fromState.ColorIndex > 0))
                {
                    return FsmEditorStyles.CustomLinkColors[fromState.ColorIndex];
                }
            }
            return FsmEditorStyles.LinkColors[(int) drawState];
        }

        private static Color GetTransitionBoxColor(FsmState state, FsmTransition transition)
        {
            if (transition.ColorIndex > 0)
            {
                return (Color) ((Color.white * 0.5f) + (Fsm.StateColors[transition.ColorIndex] * 0.5f));
            }
            return (Color) ((Color.white * 0.5f) + (Fsm.StateColors[state.ColorIndex] * 0.5f));
        }

        private static Color GetTransitionContentColor(FsmState state, FsmTransition transition)
        {
            return Color.black;
        }

        public static Vector2 GetViewCenter()
        {
            Rect view = FsmEditor.GraphView.view;
            return new Vector2(FsmEditor.Selection.ScrollPosition.x + (view.width * 0.5f), FsmEditor.Selection.ScrollPosition.y + (view.height * 0.5f));
        }

        private void HandleDragAndDrop()
        {
            if (this.canvas.Contains(this.currentMousePos) && (DragAndDropManager.mode == DragAndDropManager.DragMode.AddAction))
            {
                DragAndDrop.visualMode = DragAndDropVisualMode.Copy;
            }
        }

        public bool IsStateOffscreen(FsmState state)
        {
            if (state == null)
            {
                return false;
            }
            return ((state.Position.x < (FsmEditor.Selection.ScrollPosition.x + 0f)) || ((state.Position.y < (FsmEditor.Selection.ScrollPosition.y + 0f)) || ((((state.Position.x + state.Position.width) + 0f) > (FsmEditor.Selection.ScrollPosition.x + this.view.width)) || (((state.Position.y + state.Position.height) + 0f) > (FsmEditor.Selection.ScrollPosition.y + this.view.height)))));
        }

        private void MouseDown()
        {
            switch (Event.current.button)
            {
                case 0:
                case 1:
                    if (this.mouseOverGlobalTransition != null)
                    {
                        if (Event.current.clickCount > 1)
                        {
                            FsmEditor.Inspector.SetMode(HutongGames.PlayMakerEditor.InspectorMode.EventManager);
                        }
                        FsmEditor.EventManager.SelectEvent(this.mouseOverGlobalTransition.FsmEvent, true);
                    }
                    if (this.mouseOverTransition == null)
                    {
                        if (this.mouseOverState != null)
                        {
                            FsmEditor.Selection.SelectState(this.mouseOverState, Event.current.shift, Event.current.alt);
                            FsmEditor.Inspector.SetMode(HutongGames.PlayMakerEditor.InspectorMode.StateInspector);
                            this.frameState = true;
                            if (Event.current.button == 0)
                            {
                                if (this.draggingMode != DraggingMode.State)
                                {
                                    this.MouseDragStart();
                                }
                                this.draggingMode = DraggingMode.State;
                                if (Event.current.alt && Application.isPlaying)
                                {
                                    FsmTransition transition = FsmEditor.Builder.FindTransitionToState(this.mouseOverState);
                                    if (transition != null)
                                    {
                                        FsmEditor.SelectedFsm.Event(transition.FsmEvent);
                                        FsmEditor.Selection.SelectTransition(null);
                                    }
                                    else
                                    {
                                        Debug.Log("No Transition to State: " + this.mouseOverState.Name);
                                        EditorApplication.Beep();
                                    }
                                }
                            }
                        }
                        else
                        {
                            FsmEditor.Selection.SelectState(null, Event.current.shift, Event.current.alt);
                            if (Event.current.button == 0)
                            {
                                if (this.draggingMode != DraggingMode.Selection)
                                {
                                    this.MouseDragStart();
                                }
                                this.draggingMode = DraggingMode.Selection;
                            }
                        }
                        break;
                    }
                    if (Event.current.alt)
                    {
                        FsmEditor.SelectState(FsmEditor.SelectStateByName(this.mouseOverTransition.ToState), true);
                        FsmEditor.Inspector.SetMode(HutongGames.PlayMakerEditor.InspectorMode.StateInspector);
                    }
                    else
                    {
                        FsmEditor.Selection.SelectState(this.mouseOverState, Event.current.shift, false);
                    }
                    if (FsmEditor.SelectedState == this.mouseOverState)
                    {
                        FsmEditor.Selection.SelectTransition(this.mouseOverTransition);
                        if (Event.current.clickCount > 1)
                        {
                            FsmEditor.Inspector.SetMode(HutongGames.PlayMakerEditor.InspectorMode.EventManager);
                        }
                        FsmEditor.EventManager.SelectEvent(this.mouseOverTransition.FsmEvent, true);
                    }
                    if (Event.current.button == 0)
                    {
                        if (this.draggingMode != DraggingMode.Transition)
                        {
                            this.MouseDragStart();
                        }
                        this.draggingMode = DraggingMode.Transition;
                        if (Event.current.alt && Application.isPlaying)
                        {
                            FsmEditor.SelectedFsm.Event(this.mouseOverTransition.FsmEvent);
                        }
                    }
                    break;

                case 2:
                    if (this.draggingMode != DraggingMode.Canvas)
                    {
                        this.MouseDragStart();
                    }
                    this.draggingMode = DraggingMode.Canvas;
                    break;
            }
            FsmEditor.RepaintAll();
        }

        private void MouseDrag()
        {
            FsmEditor.Repaint(false);
            switch (this.draggingMode)
            {
                case DraggingMode.Canvas:
                {
                    FsmSelection selection = FsmEditor.Selection;
                    selection.ScrollPosition -= Event.current.delta;
                    this.panToPositionEnd = FsmEditor.Selection.ScrollPosition;
                    FsmEditor.Repaint(false);
                    return;
                }
                case DraggingMode.State:
                    if (this.dragStarted)
                    {
                        this.DoDragStates();
                        return;
                    }
                    this.dragStarted = this.OverDragThreshold();
                    if (!this.dragStarted)
                    {
                        break;
                    }
                    FsmEditor.RegisterUndo("Move State");
                    return;

                case DraggingMode.Transition:
                    if (this.mouseOverState != FsmEditor.SelectedState)
                    {
                        this.dragStarted = true;
                    }
                    if (!this.dragStarted)
                    {
                        break;
                    }
                    this.DoAutoPan();
                    return;

                case DraggingMode.Selection:
                    if (!this.dragStarted)
                    {
                        this.dragStarted = this.OverDragThreshold();
                    }
                    break;

                default:
                    return;
            }
        }

        private void MouseDragStart()
        {
            this.dragStartPos = this.currentMousePos;
            this.dragStarted = false;
            this.dragStartPositions = new List<Vector2>();
            foreach (FsmState state in FsmEditor.Selection.States)
            {
                this.dragStartPositions.Add(new Vector2(state.Position.x, state.Position.y));
            }
        }

        private void MouseUp()
        {
            FsmEditor.Repaint(false);
            switch (this.draggingMode)
            {
                case DraggingMode.State:
                    if (!this.dragStarted)
                    {
                        if ((FsmEditor.SelectedState != null) && EditorGUI.actionKey)
                        {
                            if (Event.current.shift)
                            {
                                EditorCommands.DeleteSelectedState();
                            }
                            else
                            {
                                EditorCommands.AddTransitionToSelectedState();
                                this.mouseOverTransition = FsmEditor.SelectedTransition;
                                this.mouseOverGlobalTransition = null;
                                this.GenerateContextMenu().ShowAsContext();
                            }
                        }
                        break;
                    }
                    if (FsmEditor.Selection.ScrollPosition.x.Equals((float) 0f) && FsmEditor.Selection.ScrollPosition.y.Equals((float) 0f))
                    {
                        this.UpdateCanvasSize();
                    }
                    FsmEditor.SetFsmDirty(false, false);
                    break;

                case DraggingMode.Transition:
                    if (!this.dragStarted || (FsmEditor.SelectedTransition == null))
                    {
                        if (EditorGUI.actionKey && Event.current.shift)
                        {
                            EditorCommands.DeleteSelectedTransition();
                        }
                        break;
                    }
                    if (this.mouseOverState == null)
                    {
                        if (EditorGUI.actionKey)
                        {
                            FsmState toState = FsmEditor.Builder.AddState(new Vector2(this.dummyDraggingState.Position.x, this.dummyDraggingState.Position.y));
                            SetSelectedTransitionTarget(toState);
                            FsmEditor.SelectState(toState, false);
                        }
                        break;
                    }
                    SetSelectedTransitionTarget(this.mouseOverState);
                    break;

                case DraggingMode.Selection:
                    if (!this.dragStarted)
                    {
                        if (EditorGUI.actionKey)
                        {
                            EditorCommands.AddState(this.currentMousePos);
                        }
                        break;
                    }
                    if (FsmEditor.SelectedFsm != null)
                    {
                        bool flag = this.dragStartPos.x > this.currentMousePos.x;
                        float width = Mathf.Abs((float) (this.currentMousePos.x - this.dragStartPos.x));
                        float height = Mathf.Abs((float) (this.currentMousePos.y - this.dragStartPos.y));
                        float left = Mathf.Min(this.dragStartPos.x, this.currentMousePos.x);
                        Rect rect = new Rect(left, Mathf.Min(this.dragStartPos.y, this.currentMousePos.y), width, height);
                        List<FsmState> stateSelection = new List<FsmState>();
                        foreach (FsmState state2 in FsmEditor.SelectedFsm.States)
                        {
                            if (flag)
                            {
                                if (RectContainsOrCrossesRect(rect, state2.Position))
                                {
                                    stateSelection.Add(state2);
                                }
                            }
                            else if (RectContainsRect(rect, state2.Position))
                            {
                                stateSelection.Add(state2);
                            }
                        }
                        FsmEditor.Selection.SelectStates(stateSelection, Event.current.shift, Event.current.alt);
                    }
                    break;
            }
            this.draggingMode = DraggingMode.None;
            this.isAutoPanning = false;
            this.autoPanRampUp = 0f;
            if (((this.frameState && (Event.current.button == 0)) && (FsmEditorSettings.FrameSelectedState && !this.dragStarted)) && FsmEditor.GraphView.IsStateOffscreen(FsmEditor.SelectedState))
            {
                FsmEditor.GraphView.FrameState(FsmEditor.SelectedState);
                this.frameState = false;
            }
            FsmEditor.RepaintAll();
        }

        public void OnGUI(Rect area)
        {
            this.view = area;
            Rect rect = new Rect(0f, EditorStyles.toolbar.fixedHeight, area.width, area.height - EditorStyles.toolbar.fixedHeight);
            GUI.backgroundColor = Color.white;
            GUI.contentColor = Color.white;
            GUI.color = Color.white;
            if (Event.current.type == EventType.Repaint)
            {
                this.DrawBackground(rect);
                this.graphRepainted = true;
            }
            if (FsmEditorSettings.EnableWatermarks && FsmEditorSettings.ShowCommentsInGraphView)
            {
                this.DrawFsmDescription(FsmEditor.SelectedFsm);
            }
            GUILayout.BeginArea(area);
            FsmEditor.Selection.ScrollPosition = this.ShowScrollBars() ? GUILayout.BeginScrollView(FsmEditor.Selection.ScrollPosition, new GUILayoutOption[0]) : GUILayout.BeginScrollView(FsmEditor.Selection.ScrollPosition, FsmEditorStyles.HorizontalScrollbar, FsmEditorStyles.VerticalScrollbar, new GUILayoutOption[0]);
            if (this.isPanningToPosition)
            {
                FsmEditor.Repaint(true);
            }
            this.DrawCanvas();
            this.ProcessEvents();
            this.DoGraphGUI();
            this.DoContextMenu();
            GUILayout.EndScrollView();
            this.canvas = GUILayoutUtility.GetLastRect();
            if (EditorApplication.isPlaying)
            {
                this.DrawGameStateIcon();
            }
            DebugToolbar.OnGUI();
            GUILayout.EndArea();
            if (Event.current.type == EventType.Repaint)
            {
                if (this.takingScreenshot)
                {
                    this.CaptureNextScreenshotCell();
                }
                else
                {
                    this.DrawFrame(rect);
                    DrawHintBox(rect);
                }
            }
        }

        private bool OverDragThreshold()
        {
            Vector2 vector = this.currentMousePos - this.dragStartPos;
            return (vector.magnitude > 3f);
        }

        private void PanToPosition()
        {
            this.panToPositionLerp = Mathf.Min((float) (this.panToPositionLerp + 0.03f), (float) 1f);
            float t = Mathf.SmoothStep(0f, 1f, this.panToPositionLerp);
            Vector2 to = this.panToPositionEnd - new Vector2(this.view.width * 0.5f, this.view.height * 0.5f);
            to.x = Mathf.Clamp(to.x, 0f, this.canvasSize.x - this.view.width);
            to.y = Mathf.Clamp(to.y, 0f, this.canvasSize.y - this.view.height);
            FsmEditor.Selection.ScrollPosition = Vector2.Lerp(this.panToPositionStart, to, t);
            if (this.panToPositionLerp.Equals((float) 1f))
            {
                this.panToPositionLerp = 0f;
                this.isPanningToPosition = false;
            }
        }

        public void PasteStates()
        {
            EditorCommands.PasteStates(this.contextMenuPos);
        }

        public void PasteTemplate(object userdata)
        {
            FsmTemplate template = userdata as FsmTemplate;
            EditorCommands.PasteTemplate(template, this.contextMenuPos);
        }

        private void ProcessEvents()
        {
            if (((Event.current.type == EventType.KeyUp) && (Event.current.keyCode == KeyCode.BackQuote)) || ((Event.current.keyCode == KeyCode.BackQuote) && EditorGUI.actionKey))
            {
                FsmEditor.OpenActionWindow();
                GUIUtility.ExitGUI();
            }
            else
            {
                if (Event.current.type == EventType.KeyDown)
                {
                    this.ProcessKeys();
                }
                if (Event.current.isMouse || this.isAutoPanning)
                {
                    this.currentMousePos = Event.current.mousePosition;
                }
                if (FsmEditor.SelectedFsm != null)
                {
                    Rect rect = new Rect(this.view);
                    rect.x += FsmEditor.Selection.ScrollPosition.x;
                    rect.y += FsmEditor.Selection.ScrollPosition.y;
                    rect.Contains(this.currentMousePos);
                    this.UpdateMouseOver(this.currentMousePos);
                    if (FsmEditor.MouseUp)
                    {
                        this.MouseUp();
                    }
                    else
                    {
                        switch (Event.current.type)
                        {
                            case EventType.MouseDown:
                                this.MouseDown();
                                break;

                            case EventType.MouseDrag:
                                this.MouseDrag();
                                break;
                        }
                    }
                    if (this.dragStarted && ((this.draggingMode == DraggingMode.State) || (this.draggingMode == DraggingMode.Transition)))
                    {
                        this.MouseDrag();
                    }
                }
            }
        }

        private void ProcessKeys()
        {
            if (Event.current.keyCode == KeyCode.F1)
            {
                ToggleShowHints();
            }
            if ((Event.current.keyCode == KeyCode.F11) && (FsmEditor.SelectedFsm != null))
            {
                this.TakeScreenshot();
            }
            if (GUIUtility.hotControl == 0)
            {
                switch (Event.current.keyCode)
                {
                    case KeyCode.F:
                        if (Application.isPlaying && (FsmEditor.SelectedFsm.ActiveState != null))
                        {
                            FsmEditor.SelectState(FsmEditor.SelectedFsm.ActiveState, true);
                        }
                        else
                        {
                            this.FrameState(FsmEditor.SelectedState);
                        }
                        break;

                    case KeyCode.Home:
                        this.FrameState(FsmEditor.SelectStateByName(FsmEditor.SelectedFsm.StartState));
                        break;
                }
                if (EditorGUI.actionKey)
                {
                    switch (Event.current.keyCode)
                    {
                        case KeyCode.UpArrow:
                            FsmEditor.Builder.ToggleLinkStyle(FsmEditor.SelectedTransition);
                            break;

                        case KeyCode.DownArrow:
                            FsmEditor.Builder.SetLinkConstraint(FsmEditor.SelectedTransition, FsmTransition.CustomLinkConstraint.None);
                            return;

                        case KeyCode.RightArrow:
                            FsmEditor.Builder.SetLinkConstraint(FsmEditor.SelectedTransition, FsmTransition.CustomLinkConstraint.LockRight);
                            return;

                        case KeyCode.LeftArrow:
                            FsmEditor.Builder.SetLinkConstraint(FsmEditor.SelectedTransition, FsmTransition.CustomLinkConstraint.LockLeft);
                            return;

                        default:
                            return;
                    }
                }
            }
        }

        private static bool RectContainsOrCrossesRect(Rect rect1, Rect rect2)
        {
            return (rect1.Contains(new Vector2(rect2.xMin, rect2.yMin)) || (rect1.Contains(new Vector2(rect2.xMin, rect2.yMax)) || (rect1.Contains(new Vector2(rect2.xMax, rect2.yMin)) || rect1.Contains(new Vector2(rect2.xMax, rect2.yMax)))));
        }

        private static bool RectContainsRect(Rect rect1, Rect rect2)
        {
            if (!rect1.Contains(new Vector2(rect2.xMin, rect2.yMin)))
            {
                return false;
            }
            if (!rect1.Contains(new Vector2(rect2.xMax, rect2.yMax)))
            {
                return false;
            }
            return true;
        }

        public void ResetView()
        {
            this.UpdateCanvasSize();
        }

        public void SaveScreenShot(string filename, [Optional, DefaultParameterValue(true)] bool showConfirmDialog)
        {
            if (this.screenshotTexture == null)
            {
                Debug.LogError("Bad screenshot texture!");
            }
            else
            {
                string fullPath = Path.GetFullPath(Application.dataPath + "/../" + Path.Combine(FsmEditorSettings.ScreenshotsPath, filename) + ".png");
                Debug.Log("Saving FSM Screenshot: " + fullPath);
                if (FsmEditorUtility.CreateFilePath(fullPath))
                {
                    byte[] bytes = this.screenshotTexture.EncodeToPNG();
                    UnityEngine.Object.DestroyImmediate(this.screenshotTexture, true);
                    File.WriteAllBytes(fullPath, bytes);
                    this.takingScreenshot = false;
                    this.SetScrollPosition(this.screenshotStartScrollPosition);
                    FsmEditor.Repaint(true);
                    this.graphRepainted = false;
                    this.showSavedScreenshotdialog = showConfirmDialog;
                    this.savedScreenshot = fullPath;
                }
            }
        }

        private static void ScrollView(Vector2 deltaPos)
        {
            ScrollView(deltaPos.x, deltaPos.y);
        }

        private static void ScrollView(float dx, float dy)
        {
            Vector2 vector = new Vector2(FsmEditor.Selection.ScrollPosition.x + dx, FsmEditor.Selection.ScrollPosition.y + dy);
            FsmEditor.Selection.ScrollPosition = vector;
        }

        private void SetScrollPosition(Vector2 pos)
        {
            FsmEditor.Selection.ScrollPosition = pos;
            this.panToPositionEnd = pos;
        }

        private static void SetSelectedTransitionTarget(FsmState toState)
        {
            FsmEditor.Builder.SetTransitionTarget(FsmEditor.SelectedTransition, toState.Name);
        }

        private bool ShowScrollBars()
        {
            if (this.takingScreenshot)
            {
                return false;
            }
            if (!FsmEditorSettings.ShowScrollBars && (!this.isAutoPanning && (this.draggingMode != DraggingMode.Canvas)))
            {
                return false;
            }
            return true;
        }

        private static float SnapFloatToGrid(float x, float gridSize)
        {
            return (Mathf.Floor(x / gridSize) * gridSize);
        }

        private static void SnapToGrid()
        {
            int snapGridSize = FsmEditorSettings.SnapGridSize;
            Vector2 vector = new Vector2(FsmEditor.SelectedState.Position.x, FsmEditor.SelectedState.Position.y);
            float x = SnapFloatToGrid(vector.x, (float) snapGridSize);
            Vector2 vector2 = new Vector2(x, SnapFloatToGrid(vector.y, (float) snapGridSize));
            Vector2 offset = vector2 - vector;
            foreach (FsmState state in FsmEditor.SelectedStates)
            {
                FsmBuilder.TranslateState(state, offset);
            }
        }

        private void StartPanToPosition(Vector2 pos)
        {
            this.panToPositionStart = FsmEditor.Selection.ScrollPosition;
            this.panToPositionEnd = pos;
            this.panToPositionEnd.x = Mathf.Clamp(this.panToPositionEnd.x, 0f, this.canvasSize.x);
            this.panToPositionEnd.y = Mathf.Clamp(this.panToPositionEnd.y, 0f, this.canvasSize.y);
            Vector2 vector = this.panToPositionEnd - FsmEditor.Selection.ScrollPosition;
            if (vector.magnitude > 50f)
            {
                this.isPanningToPosition = true;
            }
        }

        public void TakeScreenshot()
        {
            if (FsmEditor.SelectedFsm != null)
            {
                this.takingScreenshot = true;
                this.screenshotView = new Rect(this.view);
                this.screenshotView.height -= EditorStyles.toolbar.fixedHeight + 2f;
                this.screenshotView.y = EditorStyles.toolbar.fixedHeight + 2f;
                this.numTilesX = (int) Mathf.Ceil(this.canvasSize.x / this.screenshotView.width);
                this.numTilesY = (int) Mathf.Ceil(this.canvasSize.y / this.screenshotView.height);
                this.screenshotWidth = (int) Mathf.Max(this.canvasSize.x, this.screenshotView.width);
                this.screenshotHeight = (int) Mathf.Max(this.canvasSize.y, this.screenshotView.height);
                this.screenshotTexture = new Texture2D(this.screenshotWidth, this.screenshotHeight, TextureFormat.RGB24, false);
                this.screenshotStartScrollPosition = FsmEditor.Selection.ScrollPosition;
                this.SetScrollPosition(new Vector2(0f, 0f));
                this.tileOffsetX = 0;
                this.tileOffsetY = 0;
                FsmEditor.Repaint(true);
                this.graphRepainted = false;
            }
        }

        private static void ToggleShowHints()
        {
            FsmEditorSettings.ShowHints = !FsmEditorSettings.ShowHints;
            FsmEditorSettings.SaveSettings();
        }

        public void Update()
        {
            if (this.showSavedScreenshotdialog && this.graphRepainted)
            {
                this.showSavedScreenshotdialog = false;
                switch (EditorUtility.DisplayDialogComplex("PlayMaker", "Saved FSM Screenshot:\n" + this.savedScreenshot, "OK", "Open", "Browse"))
                {
                    case 1:
                        EditorUtility.OpenWithDefaultApp(this.savedScreenshot);
                        break;

                    case 2:
                    {
                        string str = EditorUtility.OpenFilePanel("Open Screenshot", Path.GetDirectoryName(this.savedScreenshot), "png");
                        if (!string.IsNullOrEmpty(str))
                        {
                            EditorUtility.OpenWithDefaultApp(str);
                        }
                        break;
                    }
                }
            }
            if (this.isPanningToPosition)
            {
                this.PanToPosition();
            }
            if (this.isAutoPanning)
            {
                this.autoPanRampUp += 0.05f;
                if (this.autoPanRampUp > 1f)
                {
                    this.autoPanRampUp = 1f;
                }
            }
        }

        public void UpdateCanvasSize()
        {
            if (FsmEditor.SelectedFsm != null)
            {
                this.canvasSize = new Vector2();
                foreach (FsmState state in FsmEditor.SelectedFsm.States)
                {
                    this.canvasSize.x = Mathf.Max(this.canvasSize.x, state.Position.xMax);
                    this.canvasSize.y = Mathf.Max(this.canvasSize.y, state.Position.yMax);
                }
                this.canvasSize.x += 200f;
                this.canvasSize.y += 200f;
                this.canvasSize.x = Mathf.Min(this.canvasSize.x, 20000f);
                this.canvasSize.y = Mathf.Min(this.canvasSize.y, 20000f);
            }
        }

        private void UpdateMouseOver(Vector2 mousePos)
        {
            this.mouseOverState = null;
            this.mouseOverTransition = null;
            this.mouseOverGlobalTransition = null;
            if (FsmEditor.SelectedFsm != null)
            {
                foreach (FsmState state in FsmEditor.SelectedFsm.States)
                {
                    if (state.Position.Contains(mousePos))
                    {
                        this.mouseOverState = state;
                        int num = (int) Mathf.Floor((mousePos.y - state.Position.y) / 16f);
                        if (num > 0)
                        {
                            this.mouseOverTransition = state.Transitions[num - 1];
                        }
                    }
                    else
                    {
                        List<FsmTransition> globalTransitions = FsmEditor.Builder.GetGlobalTransitions(state);
                        if (globalTransitions.Count != 0)
                        {
                            Rect rect2 = new Rect(state.Position);
                            rect2.height = globalTransitions.Count * 16f;
                            Rect rect = rect2;
                            rect.y -= rect.height + 32f;
                            if (rect.Contains(mousePos))
                            {
                                int num2 = (int) Mathf.Floor((mousePos.y - rect.y) / 16f);
                                this.mouseOverGlobalTransition = globalTransitions[num2];
                            }
                        }
                    }
                }
            }
        }

        public bool IsDragging
        {
            get
            {
                return (this.draggingMode != DraggingMode.None);
            }
        }

        private enum DragConstraint
        {
            None,
            X,
            Y
        }

        private enum DraggingMode
        {
            None,
            Canvas,
            State,
            Transition,
            Selection
        }

        internal enum GraphViewLevel
        {
            Sys,
            Device,
            Unit,
            FSM
        }
    }
}

